/*
 * Copyright (C) Hisilicon Technologies Co., Ltd. 2012-2019. All rights reserved.
 * Description: Function of glux1605b_cmos.c
 * Author: ISP SW
 * Create: 2012/06/28
 */

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "hi_comm_sns.h"
#include "hi_comm_video.h"
#include "hi_sns_ctrl.h"
#include "mpi_isp.h"
#include "mpi_ae.h"
#include "mpi_awb.h"

#include "glux1605b_cmos_ex.h"
#include "glux1605b_cmos.h"
#ifdef __cplusplus
#if __cplusplus
extern "C"
{
#endif
#endif /* End of #ifdef __cplusplus */

#define GLUX1605B_ID 1605

/****************************************************************************
 * global variables                                                            *
 ****************************************************************************/
#define HIGHER_4BITS(x) (((x) & 0xf0000) >> 16)
#define HIGH_8BITS(x) (((x) & 0xff00) >> 8)
#define LOW_8BITS(x) ((x) & 0x00ff)

#ifndef MAX
#define MAX(a, b) (((a) < (b)) ? (b) : (a))
#endif

#ifndef MIN
#define MIN(a, b) (((a) > (b)) ? (b) : (a))
#endif


#ifndef max
#define max(a, b) (((a) < (b)) ?  (b) : (a))
#endif

#ifndef min
#define min(a, b) (((a) > (b)) ?  (b) : (a))
#endif

#define right_shift(r,x) ((r) >> (x))


    ISP_SNS_STATE_S *g_pastGlux1605b[ISP_MAX_PIPE_NUM] = {HI_NULL};
#define GLUX1605B_SENSOR_SET_CTX(dev, pstCtx) ((g_pastGlux1605b[dev]) = (pstCtx))
#define GLUX1605B_SENSOR_RESET_CTX(dev) (g_pastGlux1605b[dev] = HI_NULL)

    ISP_SNS_COMMBUS_U g_aunGlux1605bBusInfo[ISP_MAX_PIPE_NUM] = {
        [0] = {.s8I2cDev = 0},
        [1 ... ISP_MAX_PIPE_NUM - 1] = {.s8I2cDev = -1}};

    ISP_SNS_COMMBUS_U *glux1605b_get_bus_Info(VI_PIPE vi_pipe)
    {
        return &g_aunGlux1605bBusInfo[vi_pipe];
    }

    ISP_SNS_STATE_S *glux1605b_get_ctx(VI_PIPE vi_pipe)
    {
        return g_pastGlux1605b[vi_pipe];
    }

    static ISP_FSWDR_MODE_E genFSWDRMode[ISP_MAX_PIPE_NUM] = {
        [0 ... ISP_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE};

    static HI_U32 g_au32MaxTimeGetCnt[ISP_MAX_PIPE_NUM] = {0};
    static HI_U32 g_au32InitExposure[ISP_MAX_PIPE_NUM] = {0};
    static HI_U32 g_au32LinesPer500ms[ISP_MAX_PIPE_NUM] = {0};

    static HI_U16 g_au16InitWBGain[ISP_MAX_PIPE_NUM][ISP_RGB_CHN_NUM] = {{0}};
    static HI_U16 g_au16SampleRgain[ISP_MAX_PIPE_NUM] = {0};
    static HI_U16 g_au16SampleBgain[ISP_MAX_PIPE_NUM] = {0};

    static HI_BOOL g_abAERouteExValid[ISP_MAX_PIPE_NUM] = {0};
    static ISP_AE_ROUTE_S g_astInitAERoute[ISP_MAX_PIPE_NUM] = {{0}};
    static ISP_AE_ROUTE_EX_S g_astInitAERouteEx[ISP_MAX_PIPE_NUM] = {{0}};
    static ISP_AE_ROUTE_S g_astInitAERouteSF[ISP_MAX_PIPE_NUM] = {{0}};
    static ISP_AE_ROUTE_EX_S g_astInitAERouteSFEx[ISP_MAX_PIPE_NUM] = {{0}};

    static HI_BOOL bFirstFps[ISP_MAX_PIPE_NUM] = {[0 ...(ISP_MAX_PIPE_NUM - 1)] = 1};
    typedef struct hiGLUX1605B_STATE_S
    {
        HI_U8 u8Hcg;
        HI_U32 u32BRL;
        HI_U32 u32RHS1_MAX;
        HI_U32 u32RHS2_MAX;
    } GLUX1605B_STATE_S;

    GLUX1605B_STATE_S g_astglux1605bState[ISP_MAX_PIPE_NUM] = {{0}};

    static HI_U32 exp_time_rdy2write = 0;
    static HI_U8  hg_mode = 1;
    static HI_U8  gain_switch_mode = 0;
    static HI_U32 gain_db_rdy2write = 0;

/****************************************************************************
 * local variables                                                            *
 ***************************************************************************/
#define GLUX1605B_SLEEP 0x0 // bit 0
#define GLUX1605B_TEMP 0x00a6

#define GLUX1605B_VMAX_0 0x5
#define GLUX1605B_VMAX_1 0x6
#define GLUX1605B_VMAX_2 0x7
#define GLUX1605B_VMAX_3 0x8
#define GLUX1605B_EXP_CTRL_0 0xB
#define GLUX1605B_EXP_CTRL_1 0xC
#define GLUX1605B_EXP_CTRL_2 0xD
#define GLUX1605B_EXP_CTRL_3 0xE

#define GLUX1605B_PIXEL_GAIN_0 78
#define GLUX1605B_PIXEL_GAIN_1 82
#define GLUX1605B_PGA_GAIN_HG 0x11F // bit 5:0
#define GLUX1605B_PGA_GAIN_LG 0x120 // bit 3:0

// sensor gain
#define GLUX1605B_AGAIN_SWITCH 0
#define GLUX1605B_AGAIN_MIN 1024
#define GLUX1605B_AGAIN_MAX 72412

#define GLUX1605B_DGAIN_MIN 1024
#define GLUX1605B_DGAIN_MAX 67520

#define GLUX1605B_LG_RANGE 29
#define GLUX1605B_HG_RANGE 57
#define GLUX1605B_AGAIN_TBL_RANGE GLUX1605B_LG_RANGE + GLUX1605B_HG_RANGE
#define GLUX1605B_DGAIN_TBL_RANGE 519 // 实际是520

#define GLUX1605B_EXP_TIME_LMT 8

#define GLUX1605B_FULL_LINES_MAX 0x3FFFF
#define GLUX1605B_FULL_LINES_MAX_2TO1_WDR 0x966 // considering the YOUT_SIZE and bad frame

/* ****Glux1605b Register Address**** */
#define GLUX1605B_SHS1_ADDR 0x3020
#define GLUX1605B_SHS2_ADDR 0x3024
#define GLUX1605B_GAIN_ADDR 0x3014
#define GLUX1605B_HCG_ADDR 0x3009
#define GLUX1605B_VMAX_ADDR 0x3018
#define GLUX1605B_HMAX_ADDR 0x301c
#define GLUX1605B_RHS1_ADDR 0x3030
#define GLUX1605B_RHS2_ADDR 0x3034
#define GLUX1605B_Y_OUT_SIZE_ADDR 0x3418

// sensor fps mode
#define GLUX1605B_SENSOR_1080P_30FPS_LINEAR_MODE 1
#define GLUX1605B_SENSOR_1080P_30FPS_2t1_WDR_MODE 2

#define GLUX1605B_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080)

#define GLUX1605B_ERR_MODE_PRINT(pstSensorImageMode, pstSnsState)               \
    do                                                                          \
    {                                                                           \
        SNS_ERR_TRACE("Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", \
                      (pstSensorImageMode)->u16Width,                           \
                      (pstSensorImageMode)->u16Height,                          \
                      (pstSensorImageMode)->f32Fps,                             \
                      (pstSnsState)->enWDRMode);                                \
    } while (0)

    static HI_VOID cmos_get_ae_comm_default(VI_PIPE vi_pipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft,
                                            ISP_SNS_STATE_S *pstSnsState)
    {
        // printf("<%s:%d > \n", __func__, __LINE__);

        if (g_au32LinesPer500ms[vi_pipe] == 0)
        {
            pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 25 / 2; /* 30fps / 2 */
        }
        else
        {
            pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[vi_pipe];
        }
        pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd;
        pstAeSnsDft->u32FlickerFreq = 50 * 256; /* light flicker freq: 50Hz, accuracy: 256 */
        pstAeSnsDft->u32FullLinesMax = GLUX1605B_FULL_LINES_MAX;

        pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR;
        pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1;
        pstAeSnsDft->stIntTimeAccu.f32Offset = 0;

        pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE;
        pstAeSnsDft->stAgainAccu.f32Accuracy = 1;

        pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE;
        pstAeSnsDft->stDgainAccu.f32Accuracy = 1;

        pstAeSnsDft->u32ISPDgainShift = 8; /* accuracy: 8 */
        pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift;
        pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; /* max 2 */

        pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0;
        pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0;

        pstAeSnsDft->bAERouteExValid = HI_FALSE;
        pstAeSnsDft->stAERouteAttr.u32TotalNum = 0;
        pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0;
        return;
    }

    static HI_VOID cmos_get_ae_linear_default(VI_PIPE vi_pipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft,
                                              ISP_SNS_STATE_S *pstSnsState)
    {
        pstAeSnsDft->au8HistThresh[0] = 0xd;
        pstAeSnsDft->au8HistThresh[1] = 0x28;
        pstAeSnsDft->au8HistThresh[2] = 0x60; /* index 2 */
        pstAeSnsDft->au8HistThresh[3] = 0x80; /* index 3 */
        // printf("<%s:%d > \n", __func__, __LINE__);

        pstAeSnsDft->u32MaxAgain = 1024; /* max 22924 */
        pstAeSnsDft->u32MinAgain = 1024;  /* min 1024 */
        pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain;
        pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain;

        pstAeSnsDft->u32MaxDgain = 128914; /* max 128914 */
        pstAeSnsDft->u32MinDgain = 1024;   /* min 1024 */
        pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain;
        pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain;

        pstAeSnsDft->u8AeCompensation = 0x38;
        pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR;

        pstAeSnsDft->u32InitExposure = g_au32InitExposure[vi_pipe] ? g_au32InitExposure[vi_pipe] : 148859; /* init 148859 */

        // mada 初始最大曝光时间
        pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd; /* sub 2 */
        pstAeSnsDft->u32MinIntTime = 3;                         /* min 3 */
        pstAeSnsDft->u32MaxIntTimeTarget = 65535;               /* max 65535 */
        pstAeSnsDft->u32MinIntTimeTarget = 3;                   /* min 3 */
        pstAeSnsDft->bAERouteExValid = g_abAERouteExValid[vi_pipe];
        memcpy_s(&pstAeSnsDft->stAERouteAttr, sizeof(ISP_AE_ROUTE_S), &g_astInitAERoute[vi_pipe], sizeof(ISP_AE_ROUTE_S));
        memcpy_s(&pstAeSnsDft->stAERouteAttrEx, sizeof(ISP_AE_ROUTE_EX_S),
                 &g_astInitAERouteEx[vi_pipe], sizeof(ISP_AE_ROUTE_EX_S));
        return;
    }

    static HI_VOID cmos_get_ae_2to1_line_wdr_default(VI_PIPE vi_pipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft,
                                                     ISP_SNS_STATE_S *pstSnsState)
    {
        // printf("<%s:%d > \n", __func__, __LINE__);
        pstAeSnsDft->au8HistThresh[0] = 0xC;
        pstAeSnsDft->au8HistThresh[1] = 0x18;
        pstAeSnsDft->au8HistThresh[2] = 0x60; /* index 2 */
        pstAeSnsDft->au8HistThresh[3] = 0x80; /* index 3 */

        pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; /* sub 2 */
        pstAeSnsDft->u32MinIntTime = 4;                         /* min 4 */

        pstAeSnsDft->u32MaxIntTimeTarget = 65535; /* max 65535 */
        pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime;

        pstAeSnsDft->u32MaxAgain = 22924; /* max 22924 */
        pstAeSnsDft->u32MinAgain = 1024;  /* min 1024 */
        pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain;
        pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain;

        pstAeSnsDft->u32MaxDgain = 128914; /* max 128914 */
        pstAeSnsDft->u32MinDgain = 1024;   /* min 1024 */
        pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain;
        pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain;
        pstAeSnsDft->u8AeCompensation = 40; /* AeCompensation 40 */

        pstAeSnsDft->u32InitExposure = g_au32InitExposure[vi_pipe] ? g_au32InitExposure[vi_pipe] : 16462; /* init 16462 */

        if (genFSWDRMode[vi_pipe] == ISP_FSWDR_LONG_FRAME_MODE)
        {
            pstAeSnsDft->u8AeCompensation = 56; /* AeCompensation 56 */
            pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR;
        }
        else
        {
            pstAeSnsDft->u32MaxISPDgainTarget = 1024; /* max 1024 */
            pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR;
            pstAeSnsDft->u16ManRatioEnable = HI_TRUE;
            pstAeSnsDft->au32Ratio[0] = 0x100;
            pstAeSnsDft->au32Ratio[1] = 0x40;
            pstAeSnsDft->au32Ratio[2] = 0x40; /* index 2 */
        }
        pstAeSnsDft->bAERouteExValid = g_abAERouteExValid[vi_pipe];
        memcpy_s(&pstAeSnsDft->stAERouteAttr, sizeof(ISP_AE_ROUTE_S), &g_astInitAERoute[vi_pipe], sizeof(ISP_AE_ROUTE_S));
        memcpy_s(&pstAeSnsDft->stAERouteAttrEx, sizeof(ISP_AE_ROUTE_EX_S),
                 &g_astInitAERouteEx[vi_pipe], sizeof(ISP_AE_ROUTE_EX_S));
        memcpy_s(&pstAeSnsDft->stAERouteSFAttr, sizeof(ISP_AE_ROUTE_S),
                 &g_astInitAERouteSF[vi_pipe], sizeof(ISP_AE_ROUTE_S));
        memcpy_s(&pstAeSnsDft->stAERouteSFAttrEx, sizeof(ISP_AE_ROUTE_EX_S), &g_astInitAERouteSFEx[vi_pipe],
                 sizeof(ISP_AE_ROUTE_EX_S));
        return;
    }

    static HI_S32 cmos_get_ae_default(VI_PIPE vi_pipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft)
    {
        ISP_SNS_STATE_S *pstSnsState = HI_NULL;

        CMOS_CHECK_POINTER(pstAeSnsDft);
        GLUX1605B_SENSOR_GET_CTX(vi_pipe, pstSnsState);
        CMOS_CHECK_POINTER(pstSnsState);

        memset_s(&pstAeSnsDft->stAERouteAttr, sizeof(ISP_AE_ROUTE_S), 0, sizeof(ISP_AE_ROUTE_S));
        // printf("<%s:%d > \n", __func__, __LINE__);

        cmos_get_ae_comm_default(vi_pipe, pstAeSnsDft, pstSnsState);
        switch (pstSnsState->enWDRMode)
        {
        default:
        case WDR_MODE_NONE: /* linear mode */

            cmos_get_ae_linear_default(vi_pipe, pstAeSnsDft, pstSnsState);
            break;

        case WDR_MODE_2To1_LINE:

            cmos_get_ae_2to1_line_wdr_default(vi_pipe, pstAeSnsDft, pstSnsState);

            break;
        }
        return HI_SUCCESS;
    }
    static HI_VOID cmos_config_vmax(ISP_SNS_STATE_S *pstSnsState, HI_U32 u32VMAX)
    {
        // printf("<%s:%d > \n", __func__, __LINE__);
        if (pstSnsState->enWDRMode == WDR_MODE_NONE)
        {
            pstSnsState->astRegsInfo[0].astI2cData[5].u32Data = LOW_8BITS(u32VMAX);    /* index 5 */
            pstSnsState->astRegsInfo[0].astI2cData[6].u32Data = HIGH_8BITS(u32VMAX);   /* index 6 */
            pstSnsState->astRegsInfo[0].astI2cData[7].u32Data = HIGHER_4BITS(u32VMAX); /* index 7 */
        }
        else
        {
            pstSnsState->astRegsInfo[0].astI2cData[8].u32Data = LOW_8BITS(u32VMAX);     /* index 8 */
            pstSnsState->astRegsInfo[0].astI2cData[9].u32Data = HIGH_8BITS(u32VMAX);    /* index 9 */
            pstSnsState->astRegsInfo[0].astI2cData[10].u32Data = HIGHER_4BITS(u32VMAX); /* index 10 */
        }

        return;
    }

    /* the function of sensor set fps */
    static HI_VOID cmos_fps_set(VI_PIPE vi_pipe, HI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft)
    {
        ISP_SNS_STATE_S *pstSnsState = HI_NULL;
        HI_U32 u32VMAX = GLUX1605B_VMAX_LINEAR;

        CMOS_CHECK_POINTER_VOID(pstAeSnsDft);
        GLUX1605B_SENSOR_GET_CTX(vi_pipe, pstSnsState);
        CMOS_CHECK_POINTER_VOID(pstSnsState);

        return;

        switch (pstSnsState->u8ImgMode)
        {
        case GLUX1605B_SENSOR_1080P_30FPS_LINEAR_MODE:
            if ((f32Fps <= 25) && (f32Fps >= 0.119))
            {                                                                                /* fps range [0.119, 30] */
                u32VMAX = GLUX1605B_VMAX_LINEAR * 25 / SNS_DIV_0_TO_1_FLOAT(f32Fps); /* 30fps */
            }
            else
            {
                SNS_ERR_TRACE("Not support Fps: %f\n", f32Fps);
                return;
            }
            u32VMAX = (u32VMAX > GLUX1605B_FULL_LINES_MAX) ? GLUX1605B_FULL_LINES_MAX : u32VMAX;
            pstAeSnsDft->u32LinesPer500ms = GLUX1605B_VMAX_LINEAR * 12; /* 15: 30fps / 2 */
            break;

        default:
            return;
        }

        // cmos_config_vmax(pstSnsState, u32VMAX);

        if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE)
        {
            pstSnsState->u32FLStd = u32VMAX * 2; /* x2 */

            g_astglux1605bState[vi_pipe].u32RHS1_MAX =
                (u32VMAX - g_astglux1605bState[vi_pipe].u32BRL) * 2 - 21; /* (VMAX - BRL) * 2 - 21 */
        }
        else
        {
            pstSnsState->u32FLStd = u32VMAX;
        }

        pstAeSnsDft->f32Fps = f32Fps;
        pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd;
        pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2; /* sub 2 */
        pstSnsState->au32FL[0] = pstSnsState->u32FLStd;
        pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0];

        if (bFirstFps[vi_pipe])
        {
            bFirstFps[vi_pipe] = HI_FALSE;
            pstSnsState->au32FL[1] = pstSnsState->au32FL[0];
        }
        return;
    }

    static HI_VOID cmos_slow_framerate_set(VI_PIPE vi_pipe, HI_U32 u32FullLines, AE_SENSOR_DEFAULT_S *pstAeSnsDft)
    {
        ISP_SNS_STATE_S *pstSnsState = HI_NULL;

        CMOS_CHECK_POINTER_VOID(pstAeSnsDft);
        GLUX1605B_SENSOR_GET_CTX(vi_pipe, pstSnsState);
        CMOS_CHECK_POINTER_VOID(pstSnsState);
        // printf("<%s:%d > \n", __func__, __LINE__);

        if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE)
        {
            u32FullLines = (u32FullLines > 2 * GLUX1605B_FULL_LINES_MAX_2TO1_WDR) ? /* 2 * Fl */
                               2 * GLUX1605B_FULL_LINES_MAX_2TO1_WDR
                                                                                  : u32FullLines; /* 2 * Fl */
            pstSnsState->au32FL[0] = (u32FullLines >> 1) << 1;
            g_astglux1605bState[vi_pipe].u32RHS1_MAX = pstSnsState->au32FL[0] -
                                                       g_astglux1605bState[vi_pipe].u32BRL * 2 - 21; /* FL - BRL * 2 - 21 */
        }
        else
        {
            u32FullLines = (u32FullLines > GLUX1605B_FULL_LINES_MAX) ? GLUX1605B_FULL_LINES_MAX : u32FullLines;
            pstSnsState->au32FL[0] = u32FullLines;
        }

        if (pstSnsState->enWDRMode == WDR_MODE_NONE)
        {
            pstSnsState->astRegsInfo[0].astI2cData[5].u32Data = LOW_8BITS(pstSnsState->au32FL[0]);    /* index 5 */
            pstSnsState->astRegsInfo[0].astI2cData[6].u32Data = HIGH_8BITS(pstSnsState->au32FL[0]);   /* index 6 */
            pstSnsState->astRegsInfo[0].astI2cData[7].u32Data = HIGHER_4BITS(pstSnsState->au32FL[0]); /* index 7 */
        }
        else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE)
        {
            pstSnsState->astRegsInfo[0].astI2cData[8].u32Data = LOW_8BITS((pstSnsState->au32FL[0] >> 1));     /* index 8 */
            pstSnsState->astRegsInfo[0].astI2cData[9].u32Data = HIGH_8BITS((pstSnsState->au32FL[0] >> 1));    /* index 9 */
            pstSnsState->astRegsInfo[0].astI2cData[10].u32Data = HIGHER_4BITS((pstSnsState->au32FL[0] >> 1)); /* index 10 */
        }
        else
        {
        }

        pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0];
        pstAeSnsDft->u32MaxIntTime = pstSnsState->au32FL[0] - 2; /* MaxIntTime: Flstd - 2 */

        return;
    }


    /* while isp notify ae to update sensor regs, ae call these funcs. */
    static HI_VOID cmos_inttime_update(VI_PIPE vi_pipe, HI_U32 u32IntTime)
    {
        ISP_SNS_STATE_S *pstSnsState = HI_NULL;
        HI_U32 u32Value = 0;
        static HI_BOOL bFirst[ISP_MAX_PIPE_NUM] = {[0 ...(ISP_MAX_PIPE_NUM - 1)] = 1};
        static HI_U32 u32ShortIntTime[ISP_MAX_PIPE_NUM] = {0};
        static HI_U32 u32LongIntTime[ISP_MAX_PIPE_NUM] = {0};
        static HI_U32 u32RHS1[ISP_MAX_PIPE_NUM] = {0};
        static HI_U32 u32SHS1[ISP_MAX_PIPE_NUM] = {0};
        static HI_U32 u32SHS2[ISP_MAX_PIPE_NUM] = {0};

        HI_U32 u32YOUTSIZE;
        // printf("<%s:%d > \n", __func__, __LINE__);

        GLUX1605B_SENSOR_GET_CTX(vi_pipe, pstSnsState);
        CMOS_CHECK_POINTER_VOID(pstSnsState);
#if 0
        u32Value = pstSnsState->au32FL[0] - u32IntTime - 1;
        glux1605b_write_register(vi_pipe, GLUX1605B_EXP_CTRL_0, LOW_8BITS(u32Value));
        glux1605b_write_register(vi_pipe, GLUX1605B_EXP_CTRL_1, HIGH_8BITS(u32Value));
        glux1605b_write_register(vi_pipe, GLUX1605B_EXP_CTRL_2, (u32Value & 0xff0000) >> 16);
        glux1605b_write_register(vi_pipe, GLUX1605B_EXP_CTRL_3, (u32Value & 0xf000000) >> 24);
#endif

        u32Value = u32IntTime;
        u32Value = MIN(u32Value, GLUX1605B_VMAX_LINEAR);
        u32Value = MIN(MAX(u32Value, 0), (pstSnsState->au32FL[0] - 2));
        u32Value = MIN(u32Value, GLUX1605B_VMAX_LINEAR - 2);
        exp_time_rdy2write = u32Value;

        return;
    }

// #define GAIN_NODE_NUM 62
// #define AGAIN_NODE_NUM 62

#define GLUX9701_LG_RANGE 29
#define GLUX9701_HG_RANGE 57
#define GLUX9701_AGAIN_TBL_RANGE  GLUX9701_LG_RANGE + GLUX9701_HG_RANGE
    /* step 0.25x */
    static HI_U32 gain_table[GLUX9701_AGAIN_TBL_RANGE] = 
    {
        1024, 1342, 1659, 1976, 2299, 2610, 2928, 3245, 3562, 3879, 4196, 4513, 4835, 5148, 5465, 5782,
        6099, 6416, 6734, 7051, 7368, 7685, 8002, 8320, 8637, 8954, 9271, 9588, 9905, //LG end
        10185, 11313, 12441, 13569, 14697, 15826, 16954, 18082, 19878, 20338, 21466, 22595, 23723, 24851, 25979, 27107,
        28235, 29363, 30492, 31620, 32748, 33876, 35004, 36132, 38931, 38389, 39517, 40645, 41773, 42901, 44029, 45157,
        46286, 47414, 48542, 49670, 50798, 51926, 53054, 54182, 55311, 56439, 57567, 58695, 59823, 60951, 62080, 63208,
        64336, 65464, 66592, 67720, 68848, 69977, 71105, 72233, 72412
    };

static HI_VOID cmos_again_calc_table(VI_PIPE vi_pipe, HI_U32 *pu32AgainLin, HI_U32 *pu32AgainDb)
{
        int i;

        CMOS_CHECK_POINTER_VOID(pu32AgainLin);
        CMOS_CHECK_POINTER_VOID(pu32AgainDb);

        ISP_SNS_STATE_S *pstSnsState = HI_NULL;
        GLUX1605B_SENSOR_GET_CTX(vi_pipe, pstSnsState);
        CMOS_CHECK_POINTER_VOID(pstSnsState);

        if (*pu32AgainLin >= gain_table[GLUX9701_AGAIN_TBL_RANGE - 1]) {
            *pu32AgainLin = gain_table[GLUX9701_AGAIN_TBL_RANGE - 1];
            if (hg_mode == 0) {
                hg_mode = 1;
                gain_switch_mode = 1;
            }
            *pu32AgainDb = GLUX9701_AGAIN_TBL_RANGE - GLUX9701_LG_RANGE + 5;
            gain_db_rdy2write = *pu32AgainDb;
            // blc_value = black_level_table[GLUX9701_AGAIN_TBL_RANGE];
            return;
        } else {
            int i;
            for (i = 1; i <= (GLUX9701_LG_RANGE); i++) {
                if (*pu32AgainLin < gain_table[i]) {
                    *pu32AgainLin = gain_table[i - 1];
                    *pu32AgainDb = i + 1; //寄存器的值从2开始
                    if (hg_mode == 1) {
                        hg_mode = 0;
                        gain_switch_mode = 1;  
                    }
                    gain_db_rdy2write = *pu32AgainDb;
                    // blc_value = black_level_table[i - 1];
                    return ;
            }
            }
            //printf("33333333g_lcg_flg = %d, *again_lin:%d\n",g_lcg_flg, *again_lin);

            for (i = GLUX9701_LG_RANGE + 1; i < GLUX9701_AGAIN_TBL_RANGE; i++) {
                if (*pu32AgainLin < gain_table[i]) {
                    *pu32AgainLin = gain_table[i - 1];
                    *pu32AgainDb = i - GLUX9701_LG_RANGE + 4 + 1; //HG模式下从2x开始
                    if (hg_mode == 0) {
                        hg_mode = 1;
                        gain_switch_mode = 1;  
                    }
                    gain_db_rdy2write = *pu32AgainDb;
                    // blc_value = black_level_table[i - 1];
                    return;
                }
            }

        return;
    }
}

    static HI_VOID cmos_gains_update(VI_PIPE vi_pipe, HI_U32 u32Again, HI_U32 u32Dgain)
    {
        ISP_SNS_STATE_S *pstSnsState = HI_NULL;
        HI_U32 u32HCG = g_astglux1605bState[vi_pipe].u8Hcg;
        HI_U32 u32Tmp;
        // printf("<%s:%d > \n", __func__, __LINE__);

        GLUX1605B_SENSOR_GET_CTX(vi_pipe, pstSnsState);
        CMOS_CHECK_POINTER_VOID(pstSnsState);

        glux1605b_write_register(vi_pipe, GLUX1605B_PGA_GAIN_HG, u32Again);
        pstSnsState->astRegsInfo[0].astSspData[AGAIN_H_IDX].u32Data = u32Again;

        return;
    }

    static HI_VOID cmos_get_inttime_max_2to1_line(VI_PIPE vi_pipe,
                                                  HI_U32 *au32Ratio, HI_U32 *au32IntTimeMax,
                                                  HI_U32 *au32IntTimeMin, HI_U32 *pu32LFMaxIntTime)
    {
        HI_U32 u32ShortMax0 = 0;
        HI_U32 u32ShortMax = 0;
        HI_U32 u32ShortTimeMinLimit;
        ISP_SNS_STATE_S *pstSnsState = HI_NULL;

        GLUX1605B_SENSOR_GET_CTX(vi_pipe, pstSnsState);
        CMOS_CHECK_POINTER_VOID(pstSnsState);
        // printf("<%s:%d > \n", __func__, __LINE__);

        u32ShortTimeMinLimit = 4; /* u32ShortTimeMinLimit 4 */

        if (genFSWDRMode[vi_pipe] == ISP_FSWDR_LONG_FRAME_MODE)
        {
            u32ShortMax0 = pstSnsState->au32FL[1] - 6 - pstSnsState->au32WDRIntTime[0]; /* sensor limit: sub 6 */
            u32ShortMax = pstSnsState->au32FL[0] - 10;                                  /* sensor limit: sub 10 */
            u32ShortMax = (u32ShortMax0 < u32ShortMax) ? u32ShortMax0 : u32ShortMax;
            au32IntTimeMax[0] = u32ShortMax;
            au32IntTimeMin[0] = u32ShortTimeMinLimit;
            return;
        }
        else
        {
            u32ShortMax0 = ((pstSnsState->au32FL[1] - 6 - pstSnsState->au32WDRIntTime[0]) * 0x40) / /* sub 6 */
                           SNS_DIV_0_TO_1(au32Ratio[0]);
            u32ShortMax = ((pstSnsState->au32FL[0] - 6) * 0x40) / SNS_DIV_0_TO_1(au32Ratio[0] + 0x40); /* sub 6 */
            u32ShortMax = (u32ShortMax0 < u32ShortMax) ? u32ShortMax0 : u32ShortMax;
            u32ShortMax = (u32ShortMax > (g_astglux1605bState[vi_pipe].u32RHS1_MAX - 3)) /* sub 3 */
                              ? (g_astglux1605bState[vi_pipe].u32RHS1_MAX - 3)           /* sub 3 */
                              : u32ShortMax;
            u32ShortMax = (u32ShortMax == 0) ? 1 : u32ShortMax;
        }

        if (u32ShortMax >= u32ShortTimeMinLimit)
        {
            au32IntTimeMax[0] = u32ShortMax;
            au32IntTimeMax[1] = (au32IntTimeMax[0] * au32Ratio[0]) >> 6; /* shift 6 */
            au32IntTimeMin[0] = u32ShortTimeMinLimit;
            au32IntTimeMin[1] = (au32IntTimeMin[0] * au32Ratio[0]) >> 6; /* shift 6 */
        }
        else
        {
            u32ShortMax = u32ShortTimeMinLimit;

            au32IntTimeMax[0] = u32ShortMax;
            au32IntTimeMax[1] = (au32IntTimeMax[0] * 0xFFF) >> 6; /* shift 6 */
            au32IntTimeMin[0] = au32IntTimeMax[0];
            au32IntTimeMin[1] = au32IntTimeMax[1];
        }

        return;
    }

    static HI_VOID cmos_get_inttime_max(VI_PIPE vi_pipe, HI_U16 u16ManRatioEnable,
                                        HI_U32 *au32Ratio, HI_U32 *au32IntTimeMax,
                                        HI_U32 *au32IntTimeMin, HI_U32 *pu32LFMaxIntTime)
    {
        ISP_SNS_STATE_S *pstSnsState = HI_NULL;
        CMOS_CHECK_POINTER_VOID(au32Ratio);
        CMOS_CHECK_POINTER_VOID(au32IntTimeMax);
        CMOS_CHECK_POINTER_VOID(au32IntTimeMin);
        CMOS_CHECK_POINTER_VOID(pu32LFMaxIntTime);
        GLUX1605B_SENSOR_GET_CTX(vi_pipe, pstSnsState);
        CMOS_CHECK_POINTER_VOID(pstSnsState);
        // printf("<%s:%d > \n", __func__, __LINE__);

        switch (pstSnsState->enWDRMode)
        {
        case WDR_MODE_2To1_LINE:
            cmos_get_inttime_max_2to1_line(vi_pipe, au32Ratio, au32IntTimeMax, au32IntTimeMin, pu32LFMaxIntTime);
            break;
        default:
            break;
        }

        return;
    }

    /* Only used in LINE_WDR mode */
    static HI_VOID cmos_ae_fswdr_attr_set(VI_PIPE vi_pipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr)
    {
        CMOS_CHECK_POINTER_VOID(pstAeFSWDRAttr);
        // printf("<%s:%d > \n", __func__, __LINE__);

        genFSWDRMode[vi_pipe] = pstAeFSWDRAttr->enFSWDRMode;
        g_au32MaxTimeGetCnt[vi_pipe] = 0;
    }

    static HI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs)
    {
        CMOS_CHECK_POINTER(pstExpFuncs);

        memset_s(pstExpFuncs, sizeof(AE_SENSOR_EXP_FUNC_S), 0, sizeof(AE_SENSOR_EXP_FUNC_S));
        // printf("<%s:%d > \n", __func__, __LINE__);

        pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default;
        pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set;
        pstExpFuncs->pfn_cmos_slow_framerate_set = cmos_slow_framerate_set;
        pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update;
        pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update;
        pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table;
        pstExpFuncs->pfn_cmos_dgain_calc_table = HI_NULL;
        pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max;
        pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set;

        return HI_SUCCESS;
    }

// awb static param
#define CALIBRATE_STATIC_TEMP 4884
#define CALIBRATE_STATIC_WB_R_GAIN 0x1DF
#define CALIBRATE_STATIC_WB_GR_GAIN 0x100
#define CALIBRATE_STATIC_WB_GB_GAIN 0x100
#define CALIBRATE_STATIC_WB_B_GAIN 0x1DC

/* Calibration results for Auto WB Planck */
#define CALIBRATE_AWB_P1 (-39)
#define CALIBRATE_AWB_P2 295
#define CALIBRATE_AWB_Q1 0
#define CALIBRATE_AWB_A1 157585
#define CALIBRATE_AWB_B1 128
#define CALIBRATE_AWB_C1 (-105655)

/* Rgain and Bgain of the golden sample */
#define GOLDEN_RGAIN 0
#define GOLDEN_BGAIN 0
    static HI_S32 cmos_get_awb_default(VI_PIPE vi_pipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft)
    {
        ISP_SNS_STATE_S *pstSnsState = HI_NULL;

        CMOS_CHECK_POINTER(pstAwbSnsDft);
        GLUX1605B_SENSOR_GET_CTX(vi_pipe, pstSnsState);
        CMOS_CHECK_POINTER(pstSnsState);
        // printf("<%s:%d > \n", __func__, __LINE__);

        memset_s(pstAwbSnsDft, sizeof(AWB_SENSOR_DEFAULT_S), 0, sizeof(AWB_SENSOR_DEFAULT_S));
        pstAwbSnsDft->u16WbRefTemp = CALIBRATE_STATIC_TEMP;

        pstAwbSnsDft->au16GainOffset[0] = CALIBRATE_STATIC_WB_R_GAIN;
        pstAwbSnsDft->au16GainOffset[1] = CALIBRATE_STATIC_WB_GR_GAIN;
        pstAwbSnsDft->au16GainOffset[2] = CALIBRATE_STATIC_WB_GB_GAIN; /* index 2 */
        pstAwbSnsDft->au16GainOffset[3] = CALIBRATE_STATIC_WB_B_GAIN;  /* index 3 */

        pstAwbSnsDft->as32WbPara[0] = CALIBRATE_AWB_P1;
        pstAwbSnsDft->as32WbPara[1] = CALIBRATE_AWB_P2;
        pstAwbSnsDft->as32WbPara[2] = CALIBRATE_AWB_Q1; /* index 2 */
        pstAwbSnsDft->as32WbPara[3] = CALIBRATE_AWB_A1; /* index 3 */
        pstAwbSnsDft->as32WbPara[4] = CALIBRATE_AWB_B1; /* index 4 */
        pstAwbSnsDft->as32WbPara[5] = CALIBRATE_AWB_C1; /* index 5 */
        pstAwbSnsDft->u16GoldenRgain = GOLDEN_RGAIN;
        pstAwbSnsDft->u16GoldenBgain = GOLDEN_BGAIN;

        switch (pstSnsState->enWDRMode)
        {
        default:
        case WDR_MODE_NONE:
            memcpy_s(&pstAwbSnsDft->stCcm, sizeof(AWB_CCM_S), &g_stAwbCcm, sizeof(AWB_CCM_S));
            memcpy_s(&pstAwbSnsDft->stAgcTbl, sizeof(AWB_AGC_TABLE_S), &g_stAwbAgcTable, sizeof(AWB_AGC_TABLE_S));
            break;

        case WDR_MODE_2To1_LINE:
            memcpy_s(&pstAwbSnsDft->stCcm, sizeof(AWB_CCM_S), &g_stAwbCcmFsWdr, sizeof(AWB_CCM_S));
            memcpy_s(&pstAwbSnsDft->stAgcTbl, sizeof(AWB_AGC_TABLE_S), &g_stAwbAgcTableFSWDR, sizeof(AWB_AGC_TABLE_S));

            break;
        }

        pstAwbSnsDft->u16InitRgain = g_au16InitWBGain[vi_pipe][0]; /* 0: Rgain */
        pstAwbSnsDft->u16InitGgain = g_au16InitWBGain[vi_pipe][1]; /* 1: Ggain */
        pstAwbSnsDft->u16InitBgain = g_au16InitWBGain[vi_pipe][2]; /* 2: Bgain */
        pstAwbSnsDft->u16SampleRgain = g_au16SampleRgain[vi_pipe];
        pstAwbSnsDft->u16SampleBgain = g_au16SampleBgain[vi_pipe];

        return HI_SUCCESS;
    }
    static HI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs)
    {
        CMOS_CHECK_POINTER(pstExpFuncs);
        // printf("<%s:%d > \n", __func__, __LINE__);

        memset_s(pstExpFuncs, sizeof(AWB_SENSOR_EXP_FUNC_S), 0, sizeof(AWB_SENSOR_EXP_FUNC_S));
        pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default;
        return HI_SUCCESS;
    }

    static ISP_CMOS_DNG_COLORPARAM_S g_stDngColorParam = {{378, 256, 430}, {439, 256, 439}};

    static HI_VOID cmos_get_isp_dng_default(ISP_SNS_STATE_S *pstSnsState, ISP_CMOS_DEFAULT_S *pstDef)
    {
        if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE)
        {
            pstDef->stWdrSwitchAttr.au32ExpRatio[0] = 0x100;
        }
        // printf("<%s:%d > \n", __func__, __LINE__);

        memcpy_s(&pstDef->stDngColorParam, sizeof(ISP_CMOS_DNG_COLORPARAM_S), &g_stDngColorParam,
                 sizeof(ISP_CMOS_DNG_COLORPARAM_S));

        switch (pstSnsState->u8ImgMode)
        {
        default:
        case GLUX1605B_SENSOR_1080P_30FPS_LINEAR_MODE:
            pstDef->stSensorMode.stDngRawFormat.u8BitsPerSample = 12; /* 12bit */
            pstDef->stSensorMode.stDngRawFormat.u32WhiteLevel = 4095; /* max 4095 */
            break;

        case GLUX1605B_SENSOR_1080P_30FPS_2t1_WDR_MODE:
            pstDef->stSensorMode.stDngRawFormat.u8BitsPerSample = 10; /* 10bit */
            pstDef->stSensorMode.stDngRawFormat.u32WhiteLevel = 1023; /* max 1023 */
            break;
        }

        pstDef->stSensorMode.stDngRawFormat.stDefaultScale.stDefaultScaleH.u32Denominator = 1;
        pstDef->stSensorMode.stDngRawFormat.stDefaultScale.stDefaultScaleH.u32Numerator = 1;
        pstDef->stSensorMode.stDngRawFormat.stDefaultScale.stDefaultScaleV.u32Denominator = 1;
        pstDef->stSensorMode.stDngRawFormat.stDefaultScale.stDefaultScaleV.u32Numerator = 1;
        pstDef->stSensorMode.stDngRawFormat.stCfaRepeatPatternDim.u16RepeatPatternDimRows = 2; /* pattern 2 */
        pstDef->stSensorMode.stDngRawFormat.stCfaRepeatPatternDim.u16RepeatPatternDimCols = 2; /* pattern 2 */
        pstDef->stSensorMode.stDngRawFormat.stBlcRepeatDim.u16BlcRepeatRows = 2;               /* pattern 2 */
        pstDef->stSensorMode.stDngRawFormat.stBlcRepeatDim.u16BlcRepeatCols = 2;               /* pattern 2 */
        pstDef->stSensorMode.stDngRawFormat.enCfaLayout = CFALAYOUT_TYPE_RECTANGULAR;
        pstDef->stSensorMode.stDngRawFormat.au8CfaPlaneColor[0] = 0;
        pstDef->stSensorMode.stDngRawFormat.au8CfaPlaneColor[1] = 1;
        pstDef->stSensorMode.stDngRawFormat.au8CfaPlaneColor[2] = 2; /* index 2, CfaPlaneColor 2 */
        pstDef->stSensorMode.stDngRawFormat.au8CfaPattern[0] = 0;
        pstDef->stSensorMode.stDngRawFormat.au8CfaPattern[1] = 1;
        pstDef->stSensorMode.stDngRawFormat.au8CfaPattern[2] = 1; /* index 2, CfaPattern 1 */
        pstDef->stSensorMode.stDngRawFormat.au8CfaPattern[3] = 2; /* index 3, CfaPattern 2 */
        pstDef->stSensorMode.bValidDngRawFormat = HI_TRUE;
        return;
    }

    static void cmos_get_isp_linear_default(ISP_CMOS_DEFAULT_S *pstDef)
    {
        // printf("<%s:%d > \n", __func__, __LINE__);

        pstDef->unKey.bit1Demosaic = 1;
        pstDef->pstDemosaic = &g_stIspDemosaic;
        pstDef->unKey.bit1Sharpen = 1;
        pstDef->pstSharpen = &g_stIspYuvSharpen;
        pstDef->unKey.bit1Drc = 1;
        pstDef->pstDrc = &g_stIspDRC;
        pstDef->unKey.bit1BayerNr = 1;
        pstDef->pstBayerNr = &g_stIspBayerNr;
        pstDef->unKey.bit1AntiFalseColor = 1;
        pstDef->pstAntiFalseColor = &g_stIspAntiFalseColor;
        pstDef->unKey.bit1Ldci = 1;
        pstDef->pstLdci = &g_stIspLdci;
        pstDef->unKey.bit1Gamma = 1;
        pstDef->pstGamma = &g_stIspGamma;
        pstDef->unKey.bit1Detail = 1;
        pstDef->pstDetail = &g_stIspDetail;
#ifdef CONFIG_HI_ISP_CR_SUPPORT
        pstDef->unKey.bit1Ge = 1;
        pstDef->pstGe = &g_stIspGe;
#endif
        pstDef->unKey.bit1Dehaze = 1;
        pstDef->pstDehaze = &g_stIspDehaze;
        memcpy_s(&pstDef->stNoiseCalibration, sizeof(ISP_CMOS_NOISE_CALIBRATION_S),
                 &g_stIspNoiseCalibration, sizeof(ISP_CMOS_NOISE_CALIBRATION_S));
        return;
    }

    static void cmos_get_isp_2to1_line_wdr_default(ISP_CMOS_DEFAULT_S *pstDef)
    {
        // printf("<%s:%d > \n", __func__, __LINE__);

        pstDef->unKey.bit1Demosaic = 1;
        pstDef->pstDemosaic = &g_stIspDemosaicWdr;
        pstDef->unKey.bit1Sharpen = 1;
        pstDef->pstSharpen = &g_stIspYuvSharpenWdr;
        pstDef->unKey.bit1Drc = 1;
        pstDef->pstDrc = &g_stIspDRCWDR;
        pstDef->unKey.bit1Gamma = 1;
        pstDef->pstGamma = &g_stIspGammaFSWDR;
#ifdef CONFIG_HI_ISP_PREGAMMA_SUPPORT
        pstDef->unKey.bit1PreGamma = 0;
        pstDef->pstPreGamma = &g_stPreGamma;
#endif
        pstDef->unKey.bit1BayerNr = 1;
        pstDef->pstBayerNr = &g_stIspBayerNrWdr2To1;
        pstDef->unKey.bit1Detail = 1;
        pstDef->pstDetail = &g_stIspDetailWdr2To1;
#ifdef CONFIG_HI_ISP_CR_SUPPORT
        pstDef->unKey.bit1Ge = 1;
        pstDef->pstGe = &g_stIspWdrGe;
#endif
        pstDef->unKey.bit1AntiFalseColor = 1;
        pstDef->pstAntiFalseColor = &g_stIspWdrAntiFalseColor;
        pstDef->unKey.bit1Ldci = 1;
        pstDef->pstLdci = &g_stIspWdrLdci;
        pstDef->unKey.bit1Dehaze = 1;
        pstDef->pstDehaze = &g_stIspDehazeWDR;
        memcpy_s(&pstDef->stNoiseCalibration, sizeof(ISP_CMOS_NOISE_CALIBRATION_S), &g_stIspNoiseCalibration,
                 sizeof(ISP_CMOS_NOISE_CALIBRATION_S));
        return;
    }

    static HI_S32 cmos_get_isp_default(VI_PIPE vi_pipe, ISP_CMOS_DEFAULT_S *pstDef)
    {
        ISP_SNS_STATE_S *pstSnsState = HI_NULL;

        CMOS_CHECK_POINTER(pstDef);
        GLUX1605B_SENSOR_GET_CTX(vi_pipe, pstSnsState);
        CMOS_CHECK_POINTER(pstSnsState);
        // printf("<%s:%d > \n", __func__, __LINE__);

        memset_s(pstDef, sizeof(ISP_CMOS_DEFAULT_S), 0, sizeof(ISP_CMOS_DEFAULT_S));

#ifdef CONFIG_HI_ISP_CA_SUPPORT
        pstDef->unKey.bit1Ca = 1;
        pstDef->pstCa = &g_stIspCA;
#endif
        pstDef->unKey.bit1Clut = 1;
        pstDef->pstClut = &g_stIspCLUT;

        pstDef->unKey.bit1Dpc = 1;
        pstDef->pstDpc = &g_stCmosDpc;

        pstDef->unKey.bit1Wdr = 1;
        pstDef->pstWdr = &g_stIspWDR;

#ifdef CONFIG_HI_ISP_HLC_SUPPORT
        pstDef->unKey.bit1Hlc = 0;
        pstDef->pstHlc = &g_stIspHlc;
#endif
        pstDef->unKey.bit1Lsc = 1;
        pstDef->pstLsc = &g_stCmosLsc;
#ifdef CONFIG_HI_ISP_EDGEMARK_SUPPORT
        pstDef->unKey.bit1EdgeMark = 0;
        pstDef->pstEdgeMark = &g_stIspEdgeMark;
#endif
#ifdef CONFIG_HI_ISP_PREGAMMA_SUPPORT
        pstDef->unKey.bit1PreGamma = 0;
        pstDef->pstPreGamma = &g_stPreGamma;
#endif
        switch (pstSnsState->enWDRMode)
        {
        default:
        case WDR_MODE_NONE:
            cmos_get_isp_linear_default(pstDef);
            break;
        }

        pstDef->stSensorMode.u32SensorID = GLUX1605B_ID;
        pstDef->stSensorMode.u8SensorMode = pstSnsState->u8ImgMode;
        cmos_get_isp_dng_default(pstSnsState, pstDef);
        return HI_SUCCESS;
    }
    static HI_S32 cmos_get_isp_black_level(VI_PIPE vi_pipe, ISP_CMOS_BLACK_LEVEL_S *pstBlackLevel)
    {
        return HI_SUCCESS;

        HI_S32 i;
        ISP_SNS_STATE_S *pstSnsState = HI_NULL;

        CMOS_CHECK_POINTER(pstBlackLevel);
        GLUX1605B_SENSOR_GET_CTX(vi_pipe, pstSnsState);
        CMOS_CHECK_POINTER(pstSnsState);
        // printf("<%s:%d > \n", __func__, __LINE__);

        /* Don't need to update black level when iso change */
        pstBlackLevel->bUpdate = HI_FALSE;

        /* black level of linear mode */
        if (pstSnsState->enWDRMode == WDR_MODE_NONE)
        {
            for (i = 0; i < ISP_BAYER_CHN_NUM; i++)
            {
                pstBlackLevel->au16BlackLevel[i] = 0x320;
            }
        }
        return HI_SUCCESS;
    }
    static HI_VOID cmos_set_pixel_detect(VI_PIPE vi_pipe, HI_BOOL bEnable)
    {
        HI_U32 u32FullLines_5Fps, u32MaxIntTime_5Fps;
        ISP_SNS_STATE_S *pstSnsState = HI_NULL;

        GLUX1605B_SENSOR_GET_CTX(vi_pipe, pstSnsState);
        CMOS_CHECK_POINTER_VOID(pstSnsState);
        // printf("<%s:%d > \n", __func__, __LINE__);
        return;

        if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE)
        {
            return;
        }
        else
        {
            if (pstSnsState->u8ImgMode == GLUX1605B_SENSOR_1080P_30FPS_LINEAR_MODE)
            {
                u32FullLines_5Fps = (GLUX1605B_VMAX_LINEAR * 25) / 5; /* 30fps, 5fps */
            }
            else
            {
                return;
            }
        }

        u32MaxIntTime_5Fps = 4; /* u32MaxIntTime_5Fps 4 */

        if (bEnable)
        { /* setup for ISP pixel calibration mode */
            // glux1605b_write_register(vi_pipe, GLUX1605B_GAIN_ADDR, 0x00);
            //
            // glux1605b_write_register(vi_pipe, GLUX1605B_VMAX_ADDR, LOW_8BITS(u32FullLines_5Fps));
            // glux1605b_write_register(vi_pipe, GLUX1605B_VMAX_ADDR + 1, HIGH_8BITS(u32FullLines_5Fps));
            // glux1605b_write_register(vi_pipe, GLUX1605B_VMAX_ADDR + 2, HIGHER_4BITS(u32FullLines_5Fps)); /* index 2 */
            //
            // glux1605b_write_register(vi_pipe, GLUX1605B_SHS1_ADDR, LOW_8BITS(u32MaxIntTime_5Fps));
            // glux1605b_write_register(vi_pipe, GLUX1605B_SHS1_ADDR + 1, HIGH_8BITS(u32MaxIntTime_5Fps));
            // glux1605b_write_register(vi_pipe, GLUX1605B_SHS1_ADDR + 2, HIGHER_4BITS(u32MaxIntTime_5Fps)); /* index 2 */
        }
        else
        { /* setup for ISP 'normal mode' */
            // pstSnsState->u32FLStd = (pstSnsState->u32FLStd > 0x1FFFF) ? 0x1FFFF : pstSnsState->u32FLStd;
            // glux1605b_write_register(vi_pipe, GLUX1605B_VMAX_ADDR, LOW_8BITS(pstSnsState->u32FLStd));
            // glux1605b_write_register(vi_pipe, GLUX1605B_VMAX_ADDR + 1, HIGH_8BITS(pstSnsState->u32FLStd));
            // glux1605b_write_register(vi_pipe, GLUX1605B_VMAX_ADDR + 2, HIGHER_4BITS(pstSnsState->u32FLStd)); /* index 2 */
            // pstSnsState->bSyncInit = HI_FALSE;
        }

        return;
    }

    static HI_S32 cmos_set_wdr_mode(VI_PIPE vi_pipe, HI_U8 u8Mode)
    {
        return HI_SUCCESS;
        ISP_SNS_STATE_S *pstSnsState = HI_NULL;

        GLUX1605B_SENSOR_GET_CTX(vi_pipe, pstSnsState);
        CMOS_CHECK_POINTER(pstSnsState);
        // printf("<%s:%d > \n", __func__, __LINE__);

        pstSnsState->bSyncInit = HI_FALSE;

        switch (u8Mode & 0x3F)
        {
        case WDR_MODE_NONE:
            pstSnsState->enWDRMode = WDR_MODE_NONE;
            printf("linear mode\n");
            break;

        case WDR_MODE_2To1_LINE:
            pstSnsState->enWDRMode = WDR_MODE_2To1_LINE;
            printf("2to1 line WDR 1080p mode(60fps->30fps)\n");
            break;

        default:
            SNS_ERR_TRACE("NOT support this mode!\n");
            return HI_FAILURE;
        }

        memset_s(pstSnsState->au32WDRIntTime, sizeof(pstSnsState->au32WDRIntTime), 0, sizeof(pstSnsState->au32WDRIntTime));

        return HI_SUCCESS;
    }

    static HI_VOID cmos_comm_sns_reg_info_init(VI_PIPE vi_pipe, ISP_SNS_STATE_S *pstSnsState)
    {
        HI_S32 i;
        pstSnsState->astRegsInfo[0].enSnsType = ISP_SNS_SSP_TYPE; // ISP_SNS_I2C_TYPE;
        pstSnsState->astRegsInfo[0].u8Cfg2ValidDelayMax = 2; /* DelayMax 2 */
        pstSnsState->astRegsInfo[0].u32RegNum = 0;           /* RegNum 8 */
        
        for (i = 0; i < pstSnsState->astRegsInfo[0].u32RegNum; i++)
        {
            pstSnsState->astRegsInfo[0].astSspData[i].bUpdate = HI_TRUE;
            pstSnsState->astRegsInfo[0].astSspData[i].u32DevAddr = GLUX1605B_SSP_ADDR;
            // pstSnsState->astRegsInfo[0].astSspData[i].u32AddrByteNum = GLUX1605B_ADDR_BYTE;
            pstSnsState->astRegsInfo[0].astSspData[i].u32DataByteNum = GLUX1605B_SSP_DATA_BYTE;
        }

        // exp time
        pstSnsState->astRegsInfo[0].astSspData[0].u8DelayFrmNum = 0;
        pstSnsState->astRegsInfo[0].astSspData[0].u32RegAddr = GLUX1605B_EXP_CTRL_0;
        pstSnsState->astRegsInfo[0].astSspData[1].u8DelayFrmNum = 0;
        pstSnsState->astRegsInfo[0].astSspData[1].u32RegAddr = GLUX1605B_EXP_CTRL_1;
        pstSnsState->astRegsInfo[0].astSspData[2].u8DelayFrmNum = 0;                 /* index 2 */
        pstSnsState->astRegsInfo[0].astSspData[2].u32RegAddr = GLUX1605B_EXP_CTRL_2; /* index 2, index 2 */
        pstSnsState->astRegsInfo[0].astSspData[3].u8DelayFrmNum = 0;                 /* index 3 */
        pstSnsState->astRegsInfo[0].astSspData[3].u32RegAddr = GLUX1605B_EXP_CTRL_3; /* index 3 */
        // gain
        pstSnsState->astRegsInfo[0].astSspData[4].u8DelayFrmNum = 1;                  /* index 4 */
        pstSnsState->astRegsInfo[0].astSspData[4].u32RegAddr = GLUX1605B_PGA_GAIN_LG; /* index 4 */
        pstSnsState->astRegsInfo[0].astSspData[5].u8DelayFrmNum = 0;                  /* index 5 */
        pstSnsState->astRegsInfo[0].astSspData[5].u32RegAddr = GLUX1605B_PGA_GAIN_HG; /* index 5 */

        pstSnsState->astRegsInfo[0].astSspData[6].u8DelayFrmNum = 0;
        pstSnsState->astRegsInfo[0].astSspData[6].u32RegAddr = GLUX1605B_VMAX_0;
        pstSnsState->astRegsInfo[0].astSspData[7].u8DelayFrmNum = 0;
        pstSnsState->astRegsInfo[0].astSspData[7].u32RegAddr = GLUX1605B_VMAX_1;
        pstSnsState->astRegsInfo[0].astSspData[8].u8DelayFrmNum = 0;             /* index 2 */
        pstSnsState->astRegsInfo[0].astSspData[8].u32RegAddr = GLUX1605B_VMAX_2; /* index 2, index 2 */
        pstSnsState->astRegsInfo[0].astSspData[9].u8DelayFrmNum = 0;             /* index 2 */
        pstSnsState->astRegsInfo[0].astSspData[9].u32RegAddr = GLUX1605B_VMAX_3; /* index 2, index 2 */

        return;
    }
    static HI_VOID cmos_2to1_line_wdr_sns_reg_info_init(VI_PIPE vi_pipe, ISP_SNS_STATE_S *pstSnsState)
    {
        // printf("<%s:%d > \n", __func__, __LINE__);

        pstSnsState->astRegsInfo[0].astI2cData[0].u8DelayFrmNum = 0;
        pstSnsState->astRegsInfo[0].astI2cData[1].u8DelayFrmNum = 0;
        pstSnsState->astRegsInfo[0].astI2cData[2].u8DelayFrmNum = 0; /* index 2 */

        pstSnsState->astRegsInfo[0].astI2cData[5].u8DelayFrmNum = 0;                    /* index 5 */
        pstSnsState->astRegsInfo[0].astI2cData[5].u32RegAddr = GLUX1605B_SHS2_ADDR;     /* index 5 */
        pstSnsState->astRegsInfo[0].astI2cData[6].u8DelayFrmNum = 0;                    /* index 6 */
        pstSnsState->astRegsInfo[0].astI2cData[6].u32RegAddr = GLUX1605B_SHS2_ADDR + 1; /* index 6 */
        pstSnsState->astRegsInfo[0].astI2cData[7].u8DelayFrmNum = 0;                    /* index 7 */
        pstSnsState->astRegsInfo[0].astI2cData[7].u32RegAddr = GLUX1605B_SHS2_ADDR + 2; /* index 7, index 2 */

        pstSnsState->astRegsInfo[0].astI2cData[8].u8DelayFrmNum = 1;                     /* index 8 */
        pstSnsState->astRegsInfo[0].astI2cData[8].u32RegAddr = GLUX1605B_VMAX_ADDR;      /* index 8 */
        pstSnsState->astRegsInfo[0].astI2cData[9].u8DelayFrmNum = 1;                     /* index 9 */
        pstSnsState->astRegsInfo[0].astI2cData[9].u32RegAddr = GLUX1605B_VMAX_ADDR + 1;  /* index 9 */
        pstSnsState->astRegsInfo[0].astI2cData[10].u8DelayFrmNum = 1;                    /* index 10 */
        pstSnsState->astRegsInfo[0].astI2cData[10].u32RegAddr = GLUX1605B_VMAX_ADDR + 2; /* index 10, index 2 */

        pstSnsState->astRegsInfo[0].astI2cData[11].u8DelayFrmNum = 1;                    /* index 11 */
        pstSnsState->astRegsInfo[0].astI2cData[11].u32RegAddr = GLUX1605B_RHS1_ADDR;     /* index 11 */
        pstSnsState->astRegsInfo[0].astI2cData[12].u8DelayFrmNum = 1;                    /* index 12 */
        pstSnsState->astRegsInfo[0].astI2cData[12].u32RegAddr = GLUX1605B_RHS1_ADDR + 1; /* index 12 */
        pstSnsState->astRegsInfo[0].astI2cData[13].u8DelayFrmNum = 1;                    /* index 13 */
        pstSnsState->astRegsInfo[0].astI2cData[13].u32RegAddr = GLUX1605B_RHS1_ADDR + 2; /* index 13, index 2 */

        pstSnsState->astRegsInfo[0].astI2cData[14].u8DelayFrmNum = 1;                          /* index 14 */
        pstSnsState->astRegsInfo[0].astI2cData[14].u32RegAddr = GLUX1605B_Y_OUT_SIZE_ADDR;     /* index 14 */
        pstSnsState->astRegsInfo[0].astI2cData[15].u8DelayFrmNum = 1;                          /* index 15 */
        pstSnsState->astRegsInfo[0].astI2cData[15].u32RegAddr = GLUX1605B_Y_OUT_SIZE_ADDR + 1; /* index 15 */
        return;
    }

    static HI_VOID cmos_sns_reg_info_update(VI_PIPE vi_pipe, ISP_SNS_STATE_S *pstSnsState)
    {
        HI_S32 i;
        // ot_unused(vi_pipe);
          if (gain_switch_mode == 1){
              if (hg_mode == 1){
                  glux1605b_write_register(vi_pipe, GLUX1605B_PIXEL_GAIN_0, 0xFF);
                  glux1605b_write_register(vi_pipe, GLUX1605B_PIXEL_GAIN_1, 0x6);
              } else {
                  glux1605b_write_register(vi_pipe, GLUX1605B_PIXEL_GAIN_0, 0x6);
                  glux1605b_write_register(vi_pipe, GLUX1605B_PIXEL_GAIN_1, 0xFF);
              }
          }
        
          glux1605b_write_register(vi_pipe, GLUX1605B_EXP_CTRL_0, (GLUX1605B_VMAX_LINEAR - exp_time_rdy2write - 2) & 0xFF);
          glux1605b_write_register(vi_pipe, GLUX1605B_EXP_CTRL_1, right_shift((GLUX1605B_VMAX_LINEAR - exp_time_rdy2write - 2), 8) & 0xFF);
          glux1605b_write_register(vi_pipe, GLUX1605B_EXP_CTRL_2, right_shift((GLUX1605B_VMAX_LINEAR - exp_time_rdy2write - 2), 16) & 0xFF);
          glux1605b_write_register(vi_pipe, GLUX1605B_EXP_CTRL_2, right_shift((GLUX1605B_VMAX_LINEAR - exp_time_rdy2write - 2), 24) & 0xF);
          glux1605b_write_register(vi_pipe, GLUX1605B_PGA_GAIN_HG, gain_db_rdy2write & 0xFF);

        // printf("cmos_sns_reg_info_update exp_time:0x%X gain:0x%X \n", exp_time_rdy2write, gain_db_rdy2write);
        return;
    }

    static HI_S32 cmos_get_sns_regs_info(VI_PIPE vi_pipe, ISP_SNS_REGS_INFO_S *pstSnsRegsInfo)
    {
        ISP_SNS_STATE_S *pstSnsState = HI_NULL;

        CMOS_CHECK_POINTER(pstSnsRegsInfo);
        GLUX1605B_SENSOR_GET_CTX(vi_pipe, pstSnsState);
        CMOS_CHECK_POINTER(pstSnsState);

        if ((pstSnsState->bSyncInit == HI_FALSE) || (pstSnsRegsInfo->bConfig == HI_FALSE))
        {
            cmos_comm_sns_reg_info_init(vi_pipe, pstSnsState);
            // DOL 2t1 Mode Regs
            if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE)
            {
                cmos_2to1_line_wdr_sns_reg_info_init(vi_pipe, pstSnsState);
            }
            pstSnsState->bSyncInit = HI_TRUE;
        }
        else
        {
            cmos_sns_reg_info_update(vi_pipe, pstSnsState);
        }

        pstSnsRegsInfo->bConfig = HI_FALSE;
        memcpy_s(pstSnsRegsInfo, sizeof(ISP_SNS_REGS_INFO_S),
                 &pstSnsState->astRegsInfo[0], sizeof(ISP_SNS_REGS_INFO_S));
        memcpy_s(&pstSnsState->astRegsInfo[1], sizeof(ISP_SNS_REGS_INFO_S),
                 &pstSnsState->astRegsInfo[0], sizeof(ISP_SNS_REGS_INFO_S));

        pstSnsState->au32FL[1] = pstSnsState->au32FL[0];
        return HI_SUCCESS;
    }

    static HI_S32 cmos_set_image_mode(VI_PIPE vi_pipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode)
    {
        return HI_SUCCESS;

        HI_U8 u8SensorImageMode;
        ISP_SNS_STATE_S *pstSnsState = HI_NULL;

        CMOS_CHECK_POINTER(pstSensorImageMode);
        GLUX1605B_SENSOR_GET_CTX(vi_pipe, pstSnsState);
        CMOS_CHECK_POINTER(pstSnsState);

        u8SensorImageMode = pstSnsState->u8ImgMode;
        pstSnsState->bSyncInit = HI_FALSE;
        // printf("<%s:%d > \n", __func__, __LINE__);

        if (pstSensorImageMode->f32Fps <= 25)
        { /* 30fps */
            switch (pstSnsState->enWDRMode)
            {
            case WDR_MODE_NONE:
                if (GLUX1605B_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height))
                {
                    u8SensorImageMode = GLUX1605B_SENSOR_1080P_30FPS_LINEAR_MODE;
                    pstSnsState->u32FLStd = GLUX1605B_VMAX_LINEAR;
                    g_astglux1605bState[vi_pipe].u8Hcg = 0x2;
                    break;
                }
                GLUX1605B_ERR_MODE_PRINT(pstSensorImageMode, pstSnsState);
                return HI_FAILURE;
            default:
                GLUX1605B_ERR_MODE_PRINT(pstSensorImageMode, pstSnsState);
                return HI_FAILURE;
            }
        }
        if ((pstSnsState->bInit == HI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode))
        {
            /* Don't need to switch SensorImageMode */
            return ISP_DO_NOT_NEED_SWITCH_IMAGEMODE;
        }

        pstSnsState->u8ImgMode = u8SensorImageMode;
        pstSnsState->au32FL[0] = pstSnsState->u32FLStd;
        pstSnsState->au32FL[1] = pstSnsState->au32FL[0];

        return HI_SUCCESS;
    }

    static HI_VOID sensor_global_init(VI_PIPE vi_pipe)
    {
        ISP_SNS_STATE_S *pstSnsState = HI_NULL;

        GLUX1605B_SENSOR_GET_CTX(vi_pipe, pstSnsState);
        CMOS_CHECK_POINTER_VOID(pstSnsState);
        // printf("<%s:%d > \n", __func__, __LINE__);

        pstSnsState->bInit     = HI_FALSE;
        pstSnsState->bSyncInit = HI_FALSE;
        pstSnsState->u8ImgMode = GLUX1605B_SENSOR_1080P_30FPS_LINEAR_MODE;
        pstSnsState->enWDRMode = WDR_MODE_NONE;
        pstSnsState->u32FLStd  = GLUX1605B_VMAX_LINEAR;
        pstSnsState->au32FL[0] = GLUX1605B_VMAX_LINEAR;
        pstSnsState->au32FL[1] = GLUX1605B_VMAX_LINEAR;

        memset_s(&pstSnsState->astRegsInfo[0], sizeof(ISP_SNS_REGS_INFO_S), 0, sizeof(ISP_SNS_REGS_INFO_S));
        memset_s(&pstSnsState->astRegsInfo[1], sizeof(ISP_SNS_REGS_INFO_S), 0, sizeof(ISP_SNS_REGS_INFO_S));
    }

    static HI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc)
    {
        CMOS_CHECK_POINTER(pstSensorExpFunc);
        // printf("<%s:%d > \n", __func__, __LINE__);

        memset_s(pstSensorExpFunc, sizeof(ISP_SENSOR_EXP_FUNC_S), 0, sizeof(ISP_SENSOR_EXP_FUNC_S));

        pstSensorExpFunc->pfn_cmos_sensor_init = glux1605b_init;
        pstSensorExpFunc->pfn_cmos_sensor_exit = glux1605b_exit;
        pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init;
        pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode;   //不需要分辨率切换
        pstSensorExpFunc->pfn_cmos_set_wdr_mode   = cmos_set_wdr_mode;
        pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default;
        pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_isp_black_level;
        pstSensorExpFunc->pfn_cmos_set_pixel_detect = cmos_set_pixel_detect;
        pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info;

        return HI_SUCCESS;
    }

    /****************************************************************************
     * callback structure                                                       *
     ****************************************************************************/
    static HI_S32 glux1605b_set_bus_info(VI_PIPE vi_pipe, ISP_SNS_COMMBUS_U unSNSBusInfo)
    {
        g_aunGlux1605bBusInfo[vi_pipe].s8I2cDev = unSNSBusInfo.s8I2cDev;
        // printf("<%s:%d > \n", __func__, __LINE__);

        return HI_SUCCESS;
    }

    static HI_S32 sensor_ctx_init(VI_PIPE vi_pipe)
    {
        ISP_SNS_STATE_S *pastSnsStateCtx = HI_NULL;

        GLUX1605B_SENSOR_GET_CTX(vi_pipe, pastSnsStateCtx);
        // printf("<%s:%d > \n", __func__, __LINE__);

        if (pastSnsStateCtx == HI_NULL)
        {
            pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S));
            if (pastSnsStateCtx == HI_NULL)
            {
                SNS_ERR_TRACE("Isp[%d] SnsCtx malloc memory failed!\n", vi_pipe);
                return HI_ERR_ISP_NOMEM;
            }
        }

        memset_s(pastSnsStateCtx, sizeof(ISP_SNS_STATE_S), 0, sizeof(ISP_SNS_STATE_S));

        GLUX1605B_SENSOR_SET_CTX(vi_pipe, pastSnsStateCtx);

        return HI_SUCCESS;
    }

    static HI_VOID sensor_ctx_exit(VI_PIPE vi_pipe)
    {
        // printf("<%s:%d > \n", __func__, __LINE__);

        ISP_SNS_STATE_S *pastSnsStateCtx = HI_NULL;
        bFirstFps[vi_pipe] = HI_TRUE;
        GLUX1605B_SENSOR_GET_CTX(vi_pipe, pastSnsStateCtx);
        SENSOR_FREE(pastSnsStateCtx);
        GLUX1605B_SENSOR_RESET_CTX(vi_pipe);
    }

    static HI_S32 sensor_register_callback(VI_PIPE vi_pipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib)
    {
        HI_S32 s32Ret;
        ISP_SENSOR_REGISTER_S stIspRegister;
        AE_SENSOR_REGISTER_S stAeRegister;
        AWB_SENSOR_REGISTER_S stAwbRegister;
        ISP_SNS_ATTR_INFO_S stSnsAttrInfo;
        // printf("<%s:%d > \n", __func__, __LINE__);

        CMOS_CHECK_POINTER(pstAeLib);
        CMOS_CHECK_POINTER(pstAwbLib);

        s32Ret = sensor_ctx_init(vi_pipe);
        if (s32Ret != HI_SUCCESS)
        {
            return HI_FAILURE;
        }

        stSnsAttrInfo.eSensorId = GLUX1605B_ID;

        s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp);
        if (s32Ret != HI_SUCCESS)
        {
            SNS_ERR_TRACE("cmos init exp function failed!\n");
            return HI_FAILURE;
        }
        s32Ret = HI_MPI_ISP_SensorRegCallBack(vi_pipe, &stSnsAttrInfo, &stIspRegister);
        if (s32Ret != HI_SUCCESS)
        {
            SNS_ERR_TRACE("sensor register callback function failed!\n");
            return s32Ret;
        }

        s32Ret = cmos_init_ae_exp_function(&stAeRegister.stSnsExp);
        if (s32Ret != HI_SUCCESS)
        {
            SNS_ERR_TRACE("cmos init ae exp function failed!\n");
            return HI_FAILURE;
        }

        s32Ret = HI_MPI_AE_SensorRegCallBack(vi_pipe, pstAeLib, &stSnsAttrInfo, &stAeRegister);
        if (s32Ret != HI_SUCCESS)
        {
            SNS_ERR_TRACE("sensor register callback function to ae lib failed!\n");
            return s32Ret;
        }

        s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stSnsExp);
        if (s32Ret != HI_SUCCESS)
        {
            SNS_ERR_TRACE("cmos init awb exp function failed!\n");
            return HI_FAILURE;
        }

        s32Ret = HI_MPI_AWB_SensorRegCallBack(vi_pipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister);
        if (s32Ret != HI_SUCCESS)
        {
            SNS_ERR_TRACE("sensor register callback function to awb lib failed!\n");
            return s32Ret;
        }

        return HI_SUCCESS;
    }

    static HI_S32 sensor_unregister_callback(VI_PIPE vi_pipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib)
    {
        HI_S32 s32Ret;

        CMOS_CHECK_POINTER(pstAeLib);
        CMOS_CHECK_POINTER(pstAwbLib);
        // printf("<%s:%d > \n", __func__, __LINE__);

        s32Ret = HI_MPI_ISP_SensorUnRegCallBack(vi_pipe, GLUX1605B_ID);
        if (s32Ret != HI_SUCCESS)
        {
            SNS_ERR_TRACE("sensor unregister callback function failed!\n");
            return s32Ret;
        }

        s32Ret = HI_MPI_AE_SensorUnRegCallBack(vi_pipe, pstAeLib, GLUX1605B_ID);
        if (s32Ret != HI_SUCCESS)
        {
            SNS_ERR_TRACE("sensor unregister callback function to ae lib failed!\n");
            return s32Ret;
        }

        s32Ret = HI_MPI_AWB_SensorUnRegCallBack(vi_pipe, pstAwbLib, GLUX1605B_ID);
        if (s32Ret != HI_SUCCESS)
        {
            SNS_ERR_TRACE("sensor unregister callback function to awb lib failed!\n");
            return s32Ret;
        }

        sensor_ctx_exit(vi_pipe);

        return HI_SUCCESS;
    }

    static HI_S32 sensor_set_init(VI_PIPE vi_pipe, ISP_INIT_ATTR_S *pstInitAttr)
    {
        CMOS_CHECK_POINTER(pstInitAttr);
        // printf("<%s:%d > \n", __func__, __LINE__);

        g_au32InitExposure[vi_pipe] = pstInitAttr->u32Exposure;
        g_au32LinesPer500ms[vi_pipe] = pstInitAttr->u32LinesPer500ms;
        g_au16InitWBGain[vi_pipe][0] = pstInitAttr->u16WBRgain; /* 0: Rgain */
        g_au16InitWBGain[vi_pipe][1] = pstInitAttr->u16WBGgain; /* 1: Ggain */
        g_au16InitWBGain[vi_pipe][2] = pstInitAttr->u16WBBgain; /* 2: Bgain */
        g_au16SampleRgain[vi_pipe] = pstInitAttr->u16SampleRgain;
        g_au16SampleBgain[vi_pipe] = pstInitAttr->u16SampleBgain;
        g_abAERouteExValid[vi_pipe] = pstInitAttr->bAERouteExValid;

        g_abAERouteExValid[vi_pipe] = pstInitAttr->bAERouteExValid;
        memcpy_s(&g_astInitAERoute[vi_pipe], sizeof(ISP_AE_ROUTE_S), &pstInitAttr->stAERoute, sizeof(ISP_AE_ROUTE_S));
        memcpy_s(&g_astInitAERouteEx[vi_pipe], sizeof(ISP_AE_ROUTE_EX_S), &pstInitAttr->stAERouteEx,
                 sizeof(ISP_AE_ROUTE_EX_S));
        memcpy_s(&g_astInitAERouteSF[vi_pipe], sizeof(ISP_AE_ROUTE_S), &pstInitAttr->stAERouteSF, sizeof(ISP_AE_ROUTE_S));
        memcpy_s(&g_astInitAERouteSFEx[vi_pipe], sizeof(ISP_AE_ROUTE_EX_S), &pstInitAttr->stAERouteSFEx,
                 sizeof(ISP_AE_ROUTE_EX_S));

        return HI_SUCCESS;
    }

    ISP_SNS_OBJ_S stSnsGlux1605bObj = {
        .pfnRegisterCallback = sensor_register_callback,
        .pfnUnRegisterCallback = sensor_unregister_callback,
        .pfnStandby = glux1605b_standby,
        .pfnRestart = glux1605b_restart,
        .pfnMirrorFlip = HI_NULL,
        .pfnWriteReg = glux1605b_write_register,
        .pfnReadReg = glux1605b_read_register,
        .pfnSetBusInfo = glux1605b_set_bus_info,
        .pfnSetInit = sensor_set_init
    };

#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
